<template>
  <div>
    <div id="map" style="width: 100vw; height: 100vh"></div>
  </div>
</template>

<script>
import * as Cesium from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
import mapdata from "../assets/data/taipo";
import img from "../assets/arrow.jpeg";

export default {
  name: "cesium",
  data() {
    return {
      viewer: null,
      proList: {},
    };
  },
  methods: {
    initMap() {
      Cesium.Ion.defaultAccessToken =
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2ZTgxOGNhZC03NThmLTQ0NzMtOTNlYS1kNmM3YzlmZDU3NTMiLCJpZCI6MTI1NTY3LCJpYXQiOjE2NzY5MDI0MzJ9.ulIEz3NCh2cMEBiHrqIuv9I6icn5KTMMnBdy2wassoM";
      this.viewer = new Cesium.Viewer("map", {
        // 配置项
      });
    },
    addHandler() {
      const handler = new Cesium.ScreenSpaceEventHandler(
        this.viewer.scene.canvas
      );
      handler.setInputAction((movement) => {
        let pick = this.viewer.scene.pick(movement.position);
        if (!pick) return;
        console.log("pick:", pick);
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },
    calculateCount(pixel = 100, positions) {
      const viewer = this.viewer;
      const scene = viewer.scene;
      const geodesic = new Cesium.EllipsoidGeodesic();
      const width = scene.canvas.clientWidth;
      const height = scene.canvas.clientHeight;
      const left = scene.camera.getPickRay(
        new Cesium.Cartesian2((width / 2) | 0, height - 1)
      );
      const right = scene.camera.getPickRay(
        new Cesium.Cartesian2((1 + width / 2) | 0, height - 1)
      );
      const globe = scene.globe;
      const leftPosition = globe.pick(left, scene);
      const rightPosition = globe.pick(right, scene);
      if (!Cesium.defined(leftPosition) || !Cesium.defined(rightPosition)) {
        return;
      }
      const leftCartographic =
        globe.ellipsoid.cartesianToCartographic(leftPosition);
      const rightCartographic =
        globe.ellipsoid.cartesianToCartographic(rightPosition);
      geodesic.setEndPoints(leftCartographic, rightCartographic);
      //1 像素实际距离
      let pixelDistance = geodesic.surfaceDistance;

      //1 像素实际距离
      let sumLength = this.getDisTance(positions);

      const sumXY = sumLength / pixelDistance;
      const count = sumXY / pixel;

      return count.toFixed(2);
    },

    getDisTance(positions) {
      const viewer = this.viewer;
      let distance = 0;
      const scene = viewer.scene;
      const globe = scene.globe;
      for (let i = 0; i < positions.length - 1; i++) {
        /**根据经纬度计算出距离**/
        const geodesic = new Cesium.EllipsoidGeodesic();

        const start = globe.ellipsoid.cartesianToCartographic(positions[i]);
        const end = globe.ellipsoid.cartesianToCartographic(positions[i + 1]);

        geodesic.setEndPoints(start, end);
        let s = geodesic.surfaceDistance;
        //返回两点之间的距离
        s = Math.sqrt(Math.pow(s, 2) + Math.pow(start.height - end.height, 2));
        distance = distance + s;
      }

      return distance.toFixed(3);
    },
    handleData(data, height = true) {
      let arr = [];
      data.forEach((item) => {
        arr.push(item[1], item[0]);
        if (height) {
          arr.push(10);
        }
      });
      return arr;
    },
    addPolylineVolumeGeometry() {
      const viewer = this.viewer;

      mapdata.pipe_vertices.forEach((item, index) => {
        console.log(
          mapdata.pipe_length[index] / 5 < 1
            ? 1.0
            : Math.ceil(mapdata.pipe_length[index] / 5)
        );
        const material2 = new Cesium.Material({
          fabric: {
            uniforms: {
              normalMap:
                "",
              count:
                mapdata.pipe_length[index] / 5 < 1
                  ? 1.0
                  : Math.ceil(mapdata.pipe_length[index] / 5),
              speed: 2.0,
              color: Cesium.Color.WHITE,
            },
            source: `
                    uniform sampler2D normalMap;
                    uniform float count;
                    uniform vec4 color;

                    czm_material czm_getMaterial(czm_materialInput materialInput)
                    {

                        float time = czm_frameNumber / 60.0 * speed;
                        vec2 uv = materialInput.st * 2.0 - 1.0;  // [0, 1] => [-1, 1]
                        vec3 pixel =vec3(1.0);
                        float alpha = 1.0;

                        float t = fract(uv.x * count - time);

                        vec4 normalColor = texture(normalMap, vec2(fract(2.0 * t ),uv.y + 0.5));
                        pixel = normalColor.rgb;
                        vec3 fragColor =  color.rgb;
                        if(t <= 0.5){
                          if( pixel.r >0.0 && pixel.g > 0.0 && pixel.b >0.0){
                            fragColor =  pixel.rgb * color.rgb;
                          }
                        }

                        czm_material material = czm_getDefaultMaterial(materialInput);
                        material.diffuse = fragColor;
                        material.alpha = alpha;

                        return material;
                    }
                `,
          },
          translucent: function () {
            return true;
          },
        });
        // 自定义材质
        const aper2 = new Cesium.MaterialAppearance({
          material: material2,
          translucent: true,
        });

        const volume = new Cesium.PolylineVolumeGeometry({
          vertexFormat: Cesium.VertexFormat.POSITION_NORMAL_AND_ST,
          polylinePositions: Cesium.Cartesian3.fromDegreesArrayHeights(
            this.handleData(item)
          ),
          // shapePositions: [
          //   new Cesium.Cartesian2(1, 0),
          //   new Cesium.Cartesian2(0, 1),
          //   new Cesium.Cartesian2(-1, 0),
          //   new Cesium.Cartesian2(0, -1),
          // ],
          shapePositions: [
            new Cesium.Cartesian2(1, 0),
            new Cesium.Cartesian2(0.5, 0.87),
            new Cesium.Cartesian2(-0.5, 0.87),
            new Cesium.Cartesian2(-1, 0),
            new Cesium.Cartesian2(-0.5, -0.87),
            new Cesium.Cartesian2(0.5, -0.87),
          ],
          cornerType: Cesium.CornerType.BEVELED,
        });

        this.proList[index] = new Cesium.Primitive({
          geometryInstances: new Cesium.GeometryInstance({
            geometry: volume,
            id: { id: mapdata.pipe_length[index] },
          }),
          appearance: aper2,
        });

        viewer.scene.primitives.add(this.proList[index]);
      });

      //   viewer.scene.postRender.addEventListener(() => {
      //     // pixel 一般是 线宽的 5 倍  可自己调整合适的效果
      //     mapdata.pipe_vertices.forEach((item, index) => {
      //       const pixel = 20 * 10;
      //       const count = this.calculateCount(
      //         pixel,
      //         Cesium.Cartesian3.fromDegreesArray(this.handleData(item, false))
      //       );
      //       if (count) {
      //         this.proList[index].appearance.material.uniforms.count = count;
      //       }
      //     });
      //   });
    },
  },
  mounted() {
    this.initMap();
    this.addHandler();
    this.addPolylineVolumeGeometry();
    this.viewer.camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(
        114.17462772366991,
        22.454557607830566,
        1000
      ),
      duration: 0,
      complete: () => {},
    });
  },
};
</script>
